from eventServer import eventServer
import pygame
import random
import yaml

from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *

class TextureServer:
    def __init__(self):
        self.textures = {}
        self.failedTextures = []
        
        self.doTexturing = True
        
        self.textureMap = yaml.load(open("tex/textureMap.yml","r"))
        
        eventServer.register("shutdownSingletons",self.shutdown)
        
    def shutdown(self, cmd, args):
        if self.doTexturing:
            print "textureServer shutting down"
            
            glDeleteTextures(self.textures.values())
            self.textures.clear()
        
    def loadTexture(self, filename, transparent = False):
        try:
            texture = pygame.image.load('tex/%s' % filename)
        except:
            return None
        print "loading texture", filename
        w,h = texture.get_size()
        rgbTextureData = pygame.image.tostring(texture,"RGB",0)
        textureData = ""
        for i in range(0,len(rgbTextureData),3):
            r,g,b = [ord(j) for j in rgbTextureData[i:i+3]]
            if transparent and not r and not g and not b:
                a = 0
            else:
                a = 255
            textureData += chr(r) + chr(g) + chr(b) + chr(a)
        textureId = glGenTextures(1)
        glBindTexture(GL_TEXTURE_2D,textureId)
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST)
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR)
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT)
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT)
        gluBuild2DMipmaps(GL_TEXTURE_2D,GL_RGBA,w,h,GL_RGBA,GL_UNSIGNED_BYTE,textureData)
        glBindTexture(GL_TEXTURE_2D,-1)
        return textureId

    def bindTexture(self, filename, transparent = False):
        if self.textureMap.has_key(filename):
            filename = self.textureMap[filename]
        
        if filename in self.failedTextures:
            return False
        
        if not self.doTexturing:
            if not self.textures.has_key(filename):
                self.textures[filename] = (random.uniform(0,1),random.uniform(0,1),random.uniform(0,1))
            c = self.textures[filename]
            glColor3f(c[0],c[1],c[2])
            return
        
        if not self.textures.has_key((filename,transparent)):
            texture = self.loadTexture(filename,transparent)
            if texture == None:
                suffixes = [".png",".jpg",".bmp"]
                for suffix in suffixes:
                    if texture != None:
                        break
                    else:
                        texture = self.loadTexture(filename + suffix, transparent)
            if texture == None:
                self.failedTextures.append(filename)
                return False
            self.textures[(filename,transparent)] = texture
            
        id = self.textures[(filename,transparent)]
        glBindTexture(GL_TEXTURE_2D,id)
        return True
        
    def unbindTexture(self):
        if not self.doTexturing:
            glColor3f(1,1,1)
            return
        
        glBindTexture(GL_TEXTURE_2D,-1)

textureServer = TextureServer()
